﻿Imports System
Imports System.Workflow.ComponentModel
Imports System.Workflow.Runtime

Namespace System.Workflow.Activities
    <Serializable> _
    Friend Class SetStateSubscription
        Inherits StateMachineSubscription
        ' Methods
        Friend Sub New(ByVal instanceId As Guid)
            Me._instanceId = instanceId
        End Sub

        Friend Sub CreateQueue(ByVal context As ActivityExecutionContext)
            If StateMachineHelpers.IsRootExecutionContext(context) Then
                Dim service As WorkflowQueuingService = context.GetService([Of] WorkflowQueuingService)
                Dim subscription As New MessageEventSubscription("SetStateQueue", Me._instanceId)
                service.CreateWorkflowQueue("SetStateQueue", True)
                MyBase.SubscriptionId = subscription.SubscriptionId
            End If
        End Sub

        Friend Sub DeleteQueue(ByVal context As ActivityExecutionContext)
            If StateMachineHelpers.IsRootExecutionContext(context) Then
                Dim service As WorkflowQueuingService = context.GetService([Of] WorkflowQueuingService)
                service.GetWorkflowQueue("SetStateQueue")
                service.DeleteWorkflowQueue("SetStateQueue")
            End If
        End Sub

        Protected Overrides Sub Enqueue(ByVal context As ActivityExecutionContext)
            StateMachineExecutionState.Get(StateMachineHelpers.GetRootState(DirectCast(context.Activity, StateActivity))).SubscriptionManager.Enqueue(context, MyBase.SubscriptionId)
        End Sub

        Friend Overrides Sub ProcessEvent(ByVal context As ActivityExecutionContext)
            Dim args As SetStateEventArgs = [TryCast](context.GetService([Of] WorkflowQueuingService).GetWorkflowQueue("SetStateQueue").Dequeue,SetStateEventArgs)
            Dim currentState As StateActivity = StateMachineHelpers.GetCurrentState(context)
            If (currentState Is Nothing) Then
                Throw New InvalidOperationException(SR.GetStateMachineWorkflowMustHaveACurrentState)
            End If
            Dim state As StateMachineExecutionState = StateMachineExecutionState.Get(StateMachineHelpers.GetRootState(DirectCast(context.Activity, StateActivity)))
            Dim action As New SetStateAction(currentState.QualifiedName, args.TargetStateName)
            state.EnqueueAction(action)
            state.ProcessActions(context)
        End Sub

        Friend Sub Subscribe(ByVal context As ActivityExecutionContext)
            context.GetService([Of] WorkflowQueuingService).GetWorkflowQueue("SetStateQueue").RegisterForQueueItemAvailable(Me)
        End Sub

        Friend Sub Unsubscribe(ByVal context As ActivityExecutionContext)
            context.GetService([Of] WorkflowQueuingService).GetWorkflowQueue("SetStateQueue").UnregisterForQueueItemAvailable(Me)
        End Sub


        ' Fields
        Private _instanceId As Guid
    End Class
End Namespace

